import json
import re
import datetime
import time
import codecs
import sys
import logging
from socket import socket, AF_INET, SOCK_STREAM
import threading

'''
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
        prefix="localhost_access_log" suffix=".txt"
        pattern="%h %l %u @[%{yyyy-MM-dd HH:mm:ss}t]@ %{X-Real_IP}i @ %r @ %s @ %b @%D@ %F" />
'''


point = 0
config = json.loads(open(r'./checkFile.json', encoding='utf-8').read())
file = config["file"]
monitor = config["monitor"]
if monitor == -1:
    sys.exit(0)
outTime = config["outTime"]
HOST = config["sendIP"]
PORT = config["sendPort"]
ADDR = (HOST, PORT)


# 创建一个logger
logger = logging.getLogger('listen')
logger.setLevel(logging.DEBUG)

# 创建一个handler，用于写入日志文件
fh = logging.FileHandler('see.log')
fh.setLevel(logging.DEBUG)

# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)

# 给logger添加handler
logger.addHandler(fh)


def entrance():
    global point
    ReallyFile = file + getDate() + '.txt'
    f = codecs.open(ReallyFile, 'r', encoding=u'utf-8', errors='ignore')
    f.seek(point)
    lines = f.readlines()
    point = f.tell()
    if len(lines) > 0:
        for line in lines:
            checkURLResponse(line)


# 消息推送
def sendMSG(msg):
    try:
        tcpCliSock = socket(AF_INET, SOCK_STREAM)
        tcpCliSock.connect(ADDR)
        data = {"type": "forward", "monitor": monitor, "msg": msg}
        tcpCliSock.send(str(data).encode())
        tcpCliSock.close()
    except Exception as r:
        logger.error(str(r) + '--------sendMSG')
        print('请求失败，继续请求')


def checkURLResponse(line):
    pattern = re.compile('''(?<=@).*?(?=@)''')
    result = pattern.findall(line)
    times = float(result[len(result) - 1]) / 1000.0
    if times > outTime:
        getTime = re.compile('''(?<=\[).*?(?=\])''')
        sendTime = getTime.findall(line)
        sendMSG('Tomcat:  ' + result[2] + '出现响应过慢，响应状态： ' + result[3] + '  响应时间为' + str(times) + '秒,发生时间为：' + sendTime[0])


def getDate():
    return str(datetime.datetime.now().strftime('%Y-%m-%d'))


# 心跳推送
def selfHeart():
    try:
        tcpCliSock = socket(AF_INET, SOCK_STREAM)
        tcpCliSock.connect(ADDR)
        data = {"type": "heart", "monitor": monitor}
        tcpCliSock.send(str(data).encode())
        tcpCliSock.close()
    except Exception as r:
        logger.error(str(r) + '--------selfHeart')
    finally:
        threading.Timer(60, selfHeart, ()).start()


# 初始化文件指针到最后
def initFile():
    print('初始化文件指针')
    global point
    ReallyFile = file + getDate() + '.txt'
    f = codecs.open(ReallyFile, 'r', encoding=u'utf-8', errors='ignore')
    f.seek(point)
    lines = f.readlines()
    point = f.tell()
    del lines


# start 方法
def start():
    try:
        do = threading.Thread(target=entrance, )
        do.start()
        while do.is_alive():
            time.sleep(0.5)
    except Exception as r:
        logger.error(str(r))
    finally:
        threading.Timer(5, start, ()).start()


initFile()
threading.Thread(target=selfHeart, ).start()
start()
sendMSG(' 营收Tomcat 请求监控启动成功')